﻿using System;
using System.Collections.Generic;
using NServiceBus;

namespace NsbExtensions
{
    public static class TypeExtensions
    {
        public static bool IsMessageHandler(this Type t)
        {
            if (t.IsAbstract)
                return false;

            foreach (Type interfaceType in t.GetInterfaces())
            {
                Type messageType = interfaceType.GetPrimaryMessageTypeHandled();
                if (messageType != null)
                    return true;
            }

            //Type parent = t.BaseType;
            //while (parent != typeof(Object))
            //{
            //    Type messageType = parent.GetPrimaryMessageTypeHandled();
            //    if (messageType != null)
            //        return true;

            //    parent = parent.BaseType;
            //}

            return false;
        }

        public static Type GetPrimaryMessageTypeHandled(this Type t)
        {
            if (t.IsGenericType)
            {
                Type[] args = t.GetGenericArguments();
                if (args.Length != 1)
                    return null;

                if (!typeof (IMessage).IsAssignableFrom(args[0]))
                    return null;

                Type handlerType = typeof (IMessageHandler<>).MakeGenericType(args[0]);
                if (handlerType.IsAssignableFrom(t))
                    return args[0];
            }

            return null;
        }

        public static IList<Type> GetAllMessageTypesHandled(this Type t)
        {
            var found = new List<Type>();

            if (t.IsAbstract)
                return found;

            foreach (Type interfaceType in t.GetInterfaces())
            {
                Type messageType = interfaceType.GetPrimaryMessageTypeHandled();
                if (messageType != null)
                {
                    found.Add(messageType);
                }
            }

            return found;
        }
    }
}